package com.pentofab.payrollmanagement.ui.controller;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.SalaryDAO;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Department;
import com.pentofab.payrollmanagement.dao.model.Designation;
import com.pentofab.payrollmanagement.dao.model.EmpCategory;
import com.pentofab.payrollmanagement.dao.model.Employee;
import com.pentofab.payrollmanagement.dao.model.Units;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.exception.DatabaseException;
import com.pentofab.payrollmanagement.ui.control.CustomTextField;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;

public class AddEmployeeUIController extends AbstractUIController implements
		Initializable, FormValidator {

	@FXML
	Parent root;
	@FXML
	CustomTextField employeeIDField;
	@FXML
	CustomTextField employeeNameField;
	@FXML
	CustomTextField telephone1Field;
	@FXML
	CustomTextField telephone2Field;
	@FXML
	CustomTextField addressLine1Field;
	@FXML
	CustomTextField addressLine2Field;
	@FXML
	CustomTextField cityField;
	@FXML
	CustomTextField stateField;
	@FXML
	ChoiceBox<String> unitsId;
	@FXML
	CustomTextField countryField;
	@FXML
	CustomTextField zipCodeField;
	@FXML
	ChoiceBox<Department> departmentChoiceBox;
	@FXML
	ChoiceBox<Designation> designationChoiceBox;
	@FXML
	ChoiceBox<EmpCategory> categoryChoiceBox;
	@FXML
	ChoiceBox<String> sexChoiceBox;
	@FXML
	CustomTextField dojCustomTextField;
	@FXML
	CustomTextField hoursPerDayCustomTextField;
	@FXML
	CustomTextField dob;
	@FXML
	CheckBox roolsCheckBox;
	@FXML
	ChoiceBox<String> dayOfWeek;
	/*@FXML
	ChoiceBox<String> salaryProfile;
*/
	private Company company;
	private Employee employee;
	private UserAccounts logedInuser;
	private boolean updateMode = false;
	EmployeeDao empDao = PayrollApplicationFactory.getEmployeeMgmt();
	SalaryDAO salaryDAO = PayrollApplicationFactory.getSalaryDAO();
	@Override
	public Parent getView() {
		return root;
	}

	@Override
	public String getTitle() {
		return UIMessages.UITitles.ADD_EMPLOYEE;
	}

	public void save() {
		String validationMessage = getValidationMessage();
		
		if(employee!= null && !employee.getDeletionDate().trim().equals("")){
			if(!showConfirmDialog(String.format(UIMessages.MODIFY_DELETED_EMPLOYEE, employee.getEmpId())))
				return;
		}
		
		if (validationMessage != null) {
			showError(validationMessage);
		} else {
			
			Employee employee = new Employee();
//			employee.setSalaryProfile(salaryProfile.getSelectionModel().getSelectedItem());
			employee.setEmpId(employeeIDField.getText());
			employee.setEmpName(employeeNameField.getText());
			employee.setTelophone1(telephone1Field.getText());
			employee.setTelophone2(telephone2Field.getText());
			employee.setAddress1(addressLine1Field.getText());
			employee.setAddress2(addressLine2Field.getText());
			employee.setCity(cityField.getText());
			employee.setState(stateField.getText());
			employee.setCountry(countryField.getText());
			employee.setZipCode(zipCodeField.getText());
			employee.setDOJ(dojCustomTextField.getText().trim());
			employee.setDOB(dob.getText().trim());
			employee.setHoursperday(hoursPerDayCustomTextField.getText().trim());
			employee.setWeeklyOff(dayOfWeek.getSelectionModel().getSelectedItem());
			employee.setCreatedby(logedInuser.getUsername());
			employee.setModifiedBy(logedInuser.getUsername());
			Department dept = departmentChoiceBox.getSelectionModel()
					.getSelectedItem();
			String unit = unitsId.getSelectionModel().getSelectedItem();
			unit = unit.substring(0,unit.indexOf(":"));
			employee.setUnit(unit);
			employee.setDepertment(dept);
			Designation desgn = designationChoiceBox.getSelectionModel()
					.getSelectedItem();
			employee.setDesignation(desgn);
			EmpCategory category = categoryChoiceBox.getSelectionModel()
					.getSelectedItem();
			employee.setCategory(category);
			if (sexChoiceBox.getSelectionModel().getSelectedItem()
					.toLowerCase().equals("male")) {
				employee.setSex("1");
			} else {
				employee.setSex("2");
			}
			employee.setCompany(company);
			employee.setRools(roolsCheckBox.selectedProperty().get());
			try {
				if (!updateMode) {
					empDao.addEmploye(employee,true);
					showInfo(String.format(UIMessages.EMPLOYEE_ADD_SUCCESS,
							employee.getEmpId()));
					if(showConfirmDialog("Would you like to add Salary stracture for employee")){
						PayrollApplicationFactory.getMainController().showScreen(MainController.SalaryStracture, true, company,logedInuser,employee);
					}
					
				} else {
					empDao.updateEmployee(employee);
					showInfo(String.format(UIMessages.EMPLOYEE_UPDATE_SUCCESS,
							employee.getEmpId()));
				}
			} catch (DatabaseException e) {
				e.printStackTrace();
				String message = "";
				switch (e.getCode()) {
				case DatabaseException.DUPLICATE_ENTRY:
					message = UIMessages.DUPLICATE_EMPLOYEE_ENTRY_ERROR_MESSAGE;
					break;
				case DatabaseException.UNKNOWN_ERROR:
				default:
					message = UIMessages.UNKNOW_DATABASE_ERROR;
					break;
				}
				showError(message);
			} catch (Exception e) {
				e.printStackTrace();
				showError(UIMessages.UNKNOW_DATABASE_ERROR);
			}
		}
	}

	public void reset() {
		if (this.employee != null) {
			refreshUI(this.company, this.employee,this.logedInuser);
		} else {
			refreshUI(this.company,this.logedInuser);
		}
	}

	public void goBack() {
		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
	}

	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
	}

	@Override
	public void refreshUI(Object... args) {
		
		this.employeeIDField.setEditable(false);
		if (args != null && args.length > 0) {
			this.company = (Company) args[0];
			
			
			try {
				
				List<Department> departments = empDao
						.getAllDepartments(this.company.getCompanyID());
				ObservableList<Department> departmentsObservableList = FXCollections.observableArrayList();
				departmentsObservableList.addAll(departments);
				this.departmentChoiceBox.getItems().clear();
				this.departmentChoiceBox.getItems().addAll(departmentsObservableList);
			
				List<Units> unitList = empDao.getUnits(company.getCompanyID());
				ObservableList<String> unitStringList = FXCollections.observableArrayList();
				for(int i = 0; i < unitList.size(); i++){
					
					unitStringList.add(unitList.get(i).getUnitId()+":"+unitList.get(i).getName());
				}
				this.unitsId.getItems().clear();
				this.unitsId.getItems().addAll(unitStringList);
				List<Designation> designations = empDao
						.getAllDesignation(this.company.getCompanyID());
				System.out.println("designations : "+designations);
				
				ObservableList<Designation> designationsObservableList = FXCollections.observableArrayList();
				designationsObservableList.addAll(designations);
				this.designationChoiceBox.getItems().clear();
				this.designationChoiceBox.getItems().addAll(designationsObservableList);
				
				List<EmpCategory> empCategories = empDao
						.getAllEmpCategory(this.company.getCompanyID());
				ObservableList<EmpCategory> empCategoriesObservableList = FXCollections
						.observableArrayList();
				empCategoriesObservableList.addAll(empCategories);
				this.categoryChoiceBox.getItems().clear();
				this.categoryChoiceBox.getItems().addAll(empCategoriesObservableList);
			} catch (Exception e) {
				e.printStackTrace();
			}
			ObservableList<String> sexObservableList = FXCollections.observableArrayList();
			sexObservableList.add("Male");
			sexObservableList.add("Female");
			this.sexChoiceBox.getItems().clear();
			this.sexChoiceBox.getItems().addAll(sexObservableList);
			
			this.employeeIDField.clear();
			this.employeeNameField.clear();
			this.telephone1Field.clear();
			this.telephone2Field.clear();
			this.addressLine1Field.clear();
			this.addressLine2Field.clear();
			this.cityField.clear();
			this.stateField.clear();
			this.countryField.clear();
			this.zipCodeField.clear();
			dayOfWeek.getSelectionModel().clearSelection();
			departmentChoiceBox.getSelectionModel().clearSelection();
			designationChoiceBox.getSelectionModel().clearSelection();
			categoryChoiceBox.getSelectionModel().clearSelection();
			this.sexChoiceBox.getSelectionModel().clearSelection();
			this.hoursPerDayCustomTextField.clear();
			this.dojCustomTextField.clear();
			this.roolsCheckBox.selectedProperty().set(false);
		}
		
		if(args.length > 1 && args[1] instanceof UserAccounts){
			logedInuser = (UserAccounts)args[1];
			employee =null;
			
		}else if(args.length > 2 && args[2] instanceof UserAccounts){
			logedInuser = (UserAccounts)args[2];
			
		}
		if (args != null && args.length > 1 && args[1] instanceof Employee) {
			this.updateMode = true;
			this.employee = (Employee) args[1];
			
			this.employeeIDField.setText(this.employee.getEmpId());
			this.employeeIDField.disableProperty().set(true);
			this.employeeNameField.setText(this.employee.getEmpName());
			this.telephone1Field.setText(this.employee.getTelophone1());
			this.telephone2Field.setText(this.employee.getTelophone2());
			this.addressLine1Field.setText(this.employee.getAddress1());
			this.addressLine2Field.setText(this.employee.getAddress2());
			this.cityField.setText(this.employee.getCity());
			this.stateField.setText(this.employee.getState());
			this.countryField.setText(this.employee.getCountry());
			this.zipCodeField.setText(this.employee.getZipCode());
			this.dayOfWeek.getSelectionModel().select(employee.getWeeklyOff());
			
			/*if(employee.getSalaryProfile() != null){
				this.salaryProfile.getSelectionModel().select(employee.getSalaryProfile());
			}else{
				this.salaryProfile.getSelectionModel().select("");
			}*/
			
			
			int unit = 0;
			ObservableList<String> unitList = this.unitsId.getItems();
			for (int i = 0; i < unitList.size(); i++) {
				String currentUnit = unitList.get(i);
				if (currentUnit.startsWith(employee.getUnit())) {
					unit = i;
					break;
				}
			}
			this.unitsId.getSelectionModel().select(unit);
			
			int departmentIndex = 0;
			ObservableList<Department> departmentChoiceList = this.departmentChoiceBox.getItems();
			for (int i = 0; i < departmentChoiceList.size(); i++) {
				Department temp = departmentChoiceList.get(i);
				if (temp.getCode().equals(
						this.employee.getDepertment().getCode())) {
					departmentIndex = i;
					break;
				}
			}
			this.departmentChoiceBox.getSelectionModel().select(departmentIndex);
			
			int designationIndex = 0;
			ObservableList<Designation> designationChoiceList = this.designationChoiceBox
					.getItems();
			for (int i = 0; i < designationChoiceList.size(); i++) {
				Designation temp = designationChoiceList.get(i);
				if (temp.getCode().equals(
						this.employee.getDesignation().getCode())) {
					designationIndex = i;
					break;
				}
			}
			this.designationChoiceBox.getSelectionModel().select(
					designationIndex);

			int categoryIndex = 0;
			ObservableList<EmpCategory> categoryChoiceList = this.categoryChoiceBox
					.getItems();
			for (int i = 0; i < categoryChoiceList.size(); i++) {
				EmpCategory temp = categoryChoiceList.get(i);
				if (temp.getCode()
						.equals(this.employee.getCategory().getCode())) {
					categoryIndex = i;
					break;
				}
			}
			this.categoryChoiceBox.getSelectionModel().select(categoryIndex);

			if (employee.getSex().equals("M")) {
				this.sexChoiceBox.getSelectionModel().select(0);
			} else {
				this.sexChoiceBox.getSelectionModel().select(1);
			}

			this.hoursPerDayCustomTextField.setText(this.employee.getHoursperday());
			this.dojCustomTextField.setText(this.employee.getDOJ());
			this.roolsCheckBox.selectedProperty().set(this.employee.isRools());
			this.dob.setText(this.employee.getDOB());
		} else {
			this.updateMode = false;
			this.employeeIDField.clear();
			this.employeeNameField.clear();
			this.telephone1Field.clear();
			this.telephone2Field.clear();
			this.addressLine1Field.clear();
			this.addressLine2Field.clear();
			this.cityField.clear();
			this.stateField.clear();
			this.countryField.clear();
			this.departmentChoiceBox.getSelectionModel().clearSelection();
			this.designationChoiceBox.getSelectionModel().clearSelection();
			this.categoryChoiceBox.getSelectionModel().clearSelection();
			this.sexChoiceBox.getSelectionModel().clearSelection();
			this.hoursPerDayCustomTextField.clear();
			this.dojCustomTextField.clear();
			this.roolsCheckBox.selectedProperty().set(false);
			this.dob.clear();
			
			try {
				String nextEmpId= company.getCompanyID()+empDao.getNextEmpID(company.getCompanyID());
				PayRollUtility.validateEmpId(nextEmpId);
				employeeIDField.setText(nextEmpId);
			} catch (BusinessException e) {
				showError(e.getMessage());
				goBack();
			}
		}

	}

	@Override
	public boolean isValid() {
		if (employeeIDField.getText().length() < 2) {
			return false;
		}

		if (employeeNameField.getText().length() < 2) {
			return false;
		}

		if (telephone1Field.getText().length() < 5) {
			return false;
		}

		if (telephone2Field.getText().length() < 5) {
			return false;
		}

		if (addressLine1Field.getText().length() < 2) {
			return false;
		}

		if (cityField.getText().length() < 2) {
			return false;
		}

		if (stateField.getText().length() < 2) {
			return false;
		}

		if (countryField.getText().length() < 2) {
			return false;
		}

		if (zipCodeField.getText().length() < 5) {
			return false;
		}

		if (departmentChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return false;
		}

		if (designationChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return false;
		}

		if (categoryChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return false;
		}

		if (sexChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return false;
		}

		if (!PayRollUtility.isValidDate(dojCustomTextField.getText())) {
			return false;
		}

		if (Integer.parseInt(hoursPerDayCustomTextField.getText()) > 24) {
			return false;
		}
		return true;
	}

	@Override
	public String getValidationMessage() {
		
		if (employeeIDField.getText().length() < 2) {
			return UIMessages.EMPLOYEE_CODE_VALIDATION_MESSAGE;
		}
		
		
		if (employeeNameField.getText().length() < 2) {
			return UIMessages.EMPLOYEE_NAME_VALIDATION_MESSAGE;
		}

		if (telephone1Field.getText().length() < 5) {
			return UIMessages.EMPLOYEE_TELEPHONE_VALIDATION_MESSAGE;
		}

		if (addressLine1Field.getText().length() < 2) {
			return UIMessages.EMPLOYEE_ADDRESS_VALIDATION_MESSAGE;
		}

		if (cityField.getText().length() < 2) {
			return UIMessages.EMPLOYEE_CITY_VALIDATION_MESSAGE;
		}

		if (stateField.getText().length() < 2) {
			return UIMessages.EMPLOYEE_STATE_VALIDATION_MESSAGE;
		}

		if (countryField.getText().length() < 2) {
			return UIMessages.EMPLOYEE_COUNTRY_VALIDATION_MESSAGE;
		}

		if (zipCodeField.getText().length() < 5) {
			return UIMessages.EMPLOYEE_ZIPCODE_VALIDATION_MESSAGE;
		}

		if (departmentChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return UIMessages.EMPLOYEE_DEPARTMENT_VALIDATION_MESSAGE;
		}

		if (designationChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return UIMessages.EMPLOYEE_DESIGNATION_VALIDATION_MESSAGE;
		}

		if (categoryChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return UIMessages.EMPLOYEE_CATEGORY_VALIDATION_MESSAGE;
		}

		if (sexChoiceBox.getSelectionModel().getSelectedItem() == null) {
			return UIMessages.EMPLOYEE_SEX_VALIDATION_MESSAGE;
		}
		
		String doj = dojCustomTextField.getText();
		
		if (doj != null && !doj.trim().equals("")) {
			if (!PayRollUtility.isValidDate(dojCustomTextField.getText())) {
				return UIMessages.EMPLOYEE_DOJ_VALIDATION_MESSAGE;
			}
		}
		
		String dateOfBirth = dob.getText();
		if (dateOfBirth != null && !dateOfBirth.trim().equals("")) {

			if (!PayRollUtility.isValidDate(dob.getText())) {
				return UIMessages.EMPLOYEE_DOB_VALIDATION_MESSAGE;
			}

		}
		if (!hoursPerDayCustomTextField.getText().trim().equals("")){

			String hrsPerDay = hoursPerDayCustomTextField.getText().trim();
			if(!hrsPerDay.matches("[0-9]{2}:[0-9]{2}")){
				return "Invlid hours per day, Please enter time in XX:YY format";
			}
			
			if(Integer.parseInt(hrsPerDay.split(":")[0]) > 24){
			
				return UIMessages.EMPLOYEE_HOURS_VALIDATION_MESSAGE;
			}
		}
		
		if(dayOfWeek.getSelectionModel().getSelectedIndex() < 0){
			return "Please select weekly off for employee or set empty";
		}
		return null;
	}

}
